import copy
from event import OrderEvent
from info import _INSTRUMENTS_
# 　用于判断当前的订单是否submit,axeculate,
class Order(object):
    #获取signal_event的数据，并生成订单数据，判断订单是否成交, 是否直接执行到交易所
    def __init__(self,stratefy_instance):
        self.type = 'ORDER'
        self.asset=stratefy_instance.asset
        self.home_currency=stratefy_instance.home_currency
        self.max_len=stratefy_instance.max_len
        self.money=stratefy_instance.money
        print('order_self.money',self.money)
        self.events=stratefy_instance.events
        self.all_pair_name=stratefy_instance.all_pair_name
        self.data_root=stratefy_instance.data_root
        self.trade_pairs=[pair+'__'+str(frame)+'M'  for frame in stratefy_instance.time_frame  for pair in stratefy_instance.trade_pairs ]
        self.pairs=stratefy_instance.pairs
        self.time_frame=stratefy_instance.time_frame
        self.data_name=stratefy_instance.data_name
        self.symbol_data=stratefy_instance.symbol_data
        self.datas = stratefy_instance.datas
        self.leverage=stratefy_instance.leverage
        self.backtest=stratefy_instance.backtest
        self.transmit=True if self.backtest is not True else False
        self.signal_event_dict=stratefy_instance.signal_event_dict
        self.order_id=0
        self.order_info={}
        self.order_status={}
        self.order_uncompleted=[]
        #self.order_completed=[]
        self.order_event_dict={}
    #主要有以下的函数需要实现：
    def creat_order(self):
        #创建订单
        #print('创建订单')
        signal_event_key=list(self.signal_event_dict.keys())
        for key in signal_event_key:
        #for signal_event in signal_event_list:
            signal_event=self.signal_event_dict[key]
            #print('self.signal_event_list',len(self.signal_event_dict),type(self.signal_event_dict),self.signal_event_dict)
            #print('signal_event',len(signal_event),type(signal_event),signal_event)
            #把订单从signal_event转化到order中，并删除
            self.signal_event_dict.pop(key)
            self.order_id+=1
            self.order_uncompleted.append(str(self.order_id))
            pair=signal_event.pair
            size = signal_event.size
            side = signal_event.side
            exectype = signal_event.exectype
            price = signal_event.price
            limit_price = signal_event.limit_price
            take_profit_price = signal_event.take_profit_price
            stop_price = signal_event.stop_price
            time = signal_event.time
            order_id = self.order_id
            valid = signal_event.valid
            transmit = signal_event.transmit
            self.update_order_status(order_id)
            self.update_order_info(order_id)
            self.order_status[str(order_id)]['created']=True
            self.order_status[str(order_id)]['submitted']=None
            self.order_status[str(order_id)]['accepted']=None
            self.order_status[str(order_id)]['partial']=None
            self.order_status[str(order_id)]['completed']=None
            self.order_status[str(order_id)]['rejected']=None
            self.order_status[str(order_id)]['cancelled']=None
            self.order_status[str(order_id)]['expried']=None
            self.order_info[str(order_id)]={'pair':pair,
                                            'size':size,
                                            'side':side,
                                            'exectype':exectype,
                                            'price':price,
                                            'limit_price':limit_price,
                                            'take_profit_price':take_profit_price,
                                            'stop_price':stop_price,
                                            'time':time,
                                            'order_id':order_id,
                                            'valid':valid,
                                            'transmit':transmit,
                                            'margin':0
                                            }

        #如果transmit是true的话，就需要把订单直接发送到broker
        if self.transmit:
            self.execulate_order()

    def update_order_status(self,order_id):
        self.order_status[str(order_id)]={i:None
                for i in ['created','submitted',
                'accepted' ,'partial' ,'completed',
                'rejected' ,'cancelled' ,'expried' ]}
    def update_order_info(self,order_id):
        self.order_info[str(order_id)]={i:None for i in
                         ['pair','size','side','exectype',
                        'price','limit_price','take_profit_price',
                        'stop_price','time','order_id','valid',
                        'transmit','margin' ]}


    def update_order(self):
        key_list=copy.deepcopy(self.order_uncompleted)
        #print(key_list)
        #print(self.order_info)
        #分析订单是否成交，成交了就order_event
        #print('开始进行更新订单状态')
        #print(len(self.order_uncompleted))
        for key in key_list:
            order_content=self.order_info[key]
            order_id=order_content['order_id']
            exectype=order_content['exectype']
            pair=order_content['pair']
            size=order_content['size']
            time=order_content['time']
            side=order_content['side']
            #print('exectype',exectype)
            #print('event.time',event.time)
            #print("order_content['time']",order_content['time'])

            #如果是市价，马上成交
            if exectype=='MARKET':
                #如果现在时间大于订单的时间，就按照开盘价成交
                #print('event.time',event.time)
                #print("order_content['time']",order_content['time'])
                  if self.datas[pair]['time'][-1]>=order_content['time']:
                    self.order_uncompleted.remove(key)
                    price=self.datas[pair]['open'][-1]
                    margin=self.get_margin(order_id)
                    tev=OrderEvent(pair,size,side,exectype,price,time=time,margin=margin)
                    #print(order_content)
                    self.order_event_dict[order_id]=tev
            #如果是限价单，价格达到才会成交
            if exectype=='LIMIT':
                #如果是买入限价单,当bar的最低价小于当前限价的时候，就会成交
                if side in ['buy','buy_to_cover']:
                    limit_price=order_content['limit_price']
                    #print('limit_price',limit_price)
                    #print('event.l',event.l)
                    if self.datas[pair]['low'][-1]<=limit_price:
                        self.order_uncompleted.remove(key)
                        price=limit_price
                        margin=self.get_margin(order_id)
                        tev=OrderEvent(pair,size,side,exectype,price,time=time,margin=margin)
                        print('order成交了')
                        self.order_event_dict[order_id]=tev
                #如果是卖出限价单，当bar的最高价大于当前限价的时候，就会成交
                if side in ['sell','sellshort']:
                    limit_price=order_content['limit_price']
                    #print('limit_price',limit_price)
                    #print('event.h',event.h)
                    if self.datas[pair]['high'][-1]>=limit_price:
                        self.order_uncompleted.remove(key)
                        price=limit_price
                        margin=self.get_margin(order_id)
                        tev=OrderEvent(pair,size,side,exectype,price,time=time,margin=margin)
                        print('order成交了')
                        self.order_event_dict[order_id]=tev

    def get_margin(self,order_id):
        '''
        Calculate margin occupies in USD. If its online case, it
        uses actual account margin rate to scale margin used, for
        offline case it is set to be 1.
        Margin calculation for currency:
            B_USD --> `price`
            USD_A --> 1
            B_Q --> same as B_USD calculation

        Params:
        price: None, if not given, then use close price.
        identifier: str or int, str for its name, int for index in `datas`.

        Returns:
        margin: float, Margin cost(Laveraged) In USD
        '''
        order_content=self.order_info[str(order_id)]
        exectype=order_content['exectype']
        pair=order_content['pair']
        size=order_content['size']
        price=order_content['limit_price']
        #计算相应的货币对
        base_currency,quote_currency=pair.split('__')[0].split('_')
        if base_currency=='USD':
            margin_rate=1
            margin=margin_rate*size/self.leverage
        if quote_currency=='USD':
            if exectype=='MARKET':
                #如果是市价单，成交价就是最新的开盘价
                margin_rate=self.datas[pair]['open'][-1]
            if exectype=='LIMIT':
                assert price is not None,"错误：限价单没有设定价格"
                #print(order_content)
                #margin_rate=(self.datas[pair]['close'][-1]+self.datas[pair]['open'][-1])/2
                #print(margin_rate)
                margin_rate=price
            margin=margin_rate*size/self.leverage
        else:
            #margin_rate=1
            timeframe=pair.split('__')[1]
            b_usd=base_currency+'_'+self.home_currency+'__'+timeframe
            usd_b=self.home_currency+'_'+base_currency+'__'+timeframe
            #print(b_usd,usd_b,self.datas.keys())
            if b_usd in self.datas.keys():

                if exectype=='MARKET':
                    #如果是市价单，成交价就是最新的开盘价
                    margin_rate=self.datas[b_usd]['open'][-1]
                if exectype=='LIMIT':
                    margin_rate=(self.datas[b_usd]['open'][-1]+self.datas[b_usd]['close'][-1])/2
                margin=margin_rate*size/self.leverage
            if usd_b in self.datas.keys():

                if exectype=='MARKET':
                    #如果是市价单，成交价就是最新的开盘价
                    margin_rate=self.datas[usd_b]['open'][-1]
                if exectype=='LIMIT':
                    margin_rate=(self.datas[usd_b]['open'][-1]+self.datas[b_usd]['close'][-1])/2
                margin=margin_rate*size/self.leverage

        return margin





    def execulate_order(self):
        #直接执行订单到交易所
        pass
    def cancel_order(self):
        #取消订单
        pass


